package com.david.musicapp.activity

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.SeekBar
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
import com.david.core.event.MyEventBus
import com.david.core.event.Subscribe
import com.david.core.event.ThreadMode
import com.david.core.utils.*
import com.david.core.view.CharsView
import com.david.musicapp.MusicApplication
import com.david.musicapp.PlayService
import com.david.musicapp.R
import com.david.musicapp.adapter.MusicsAdapter
import com.david.musicapp.bean.Song
import com.david.musicapp.event.*
import com.david.musicapp.utils.*

/**
 * TODO 播放在线音乐
 * */
class SongActivity : BaseActivity(), PlayService.OnTimeProgressListener,
    MusicsAdapter.OnMusicItemClickListener, CharsView.OnCharSelectListener {
    private var isSeekBarTouched = false
    private lateinit var adapter: MusicsAdapter
    private lateinit var manager: LinearLayoutManager

    private lateinit var musicProgress: SeekBar
    private lateinit var musicName: TextView
    private lateinit var musicTime: TextView

    private val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
        if (result.resultCode == Activity.RESULT_OK) {
            Log.e("file", "start page result ")
            //            val intent = result.data
            // Handle the Intent
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_songs)
        musicProgress = findViewById(R.id.music_progress)
        musicName = findViewById(R.id.music_name)
        musicTime = findViewById(R.id.music_time)

        //android11管理所以文件：https://developer.android.google.cn/training/data-storage/manage-all-files?hl=zh-cn, https://juejin.cn/post/7012262477828194340
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            //检查是否已经有权限
            if (!Environment.isExternalStorageManager()) {
                //跳转新页面申请权限
                startForResult.launch(
                    Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
                )
                //                startActivityForResult( Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION), 101);
            }
        }

        registerEvent()

        initView()

        if ((System.currentTimeMillis() - MusicApplication.instance().createTime) > 1000) {
            //播放中打开的activity
            val serviceIntent = Intent(this, PlayService::class.java)
            serviceIntent.putExtra(
                PlayService.SONG_ACTION_TYPE_KEY,
                PlayService.SONG_ACTION_TYPE_GET_POSITION
            )

            startForegroundService(serviceIntent)
        } else {
            //重新打开的app
        }

        //if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        //    if (!PermissionUtils.checkPermissions(this, Manifest.permission.READ_MEDIA_AUDIO)) {
        //        requestPermission(arrayOf(Manifest.permission.READ_MEDIA_AUDIO))
        //    } else {
        //        SongHelper.getInstance().refreshList()
        //    }
        //} else {
        //    SongHelper.getInstance().refreshList()
        //    if (!PermissionUtils.checkPermissions(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
        //        requestPermission(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE))
        //    } else {
        //        SongHelper.getInstance().refreshList()
        //    }
        //}


        var songId = PreferenceUtils.getInstance().getLong("lastSongId")
        if (songId == -1L && SongHelper.getInstance().getList().isEmpty()) {
            return
        }
        if (songId == -1L) {
            songId = SongHelper.getInstance().getList()[0].id
        }



        val song = SongHelper.getInstance().getSongFromId(songId)
        if (song != null) {
            musicProgress.max = song.duration / 1000
            musicName.text = song.name
            musicProgress.progress = 0
            musicTime.text = "00:00/" + SongUtils.formatTime(musicProgress.max)

            scrollToCurrent(song)
        }

        adapter.setCurrent(songId)


        if (SongHelper.getInstance().currentId == -1L) {
            SongHelper.getInstance().currentId = songId
        }

        try {
            setSongImg(song)
        } catch (e: Exception) {
            e.printStackTrace()
        }

        parseSongId(intent)
    }

    private fun registerEvent() {
        MyEventBus.getDefault().register(this, "onMusicPlayChange", SongStartEvent::class.java)
        MyEventBus.getDefault()
            .register(this, "onMusicPositionGetted", SongPositionEvent::class.java)
        MyEventBus.getDefault().register(this, "onMusicStateChange", SongPlayStateEvent::class.java)
        MyEventBus.getDefault().register(this, "onLoopTyeChange", LoopEvent::class.java)
        MyEventBus.getDefault()
            .register(this, "onMusicListChanged", SongListChangeEvent::class.java)
    }

    private lateinit var musicList: RecyclerView
    private lateinit var musicPause: ImageView
    private lateinit var musicNext: ImageView
    private lateinit var musicPrevious: ImageView
    private lateinit var musicLoopType: ImageView
    private lateinit var musicLocationIcon: ImageView
    private lateinit var songChars: CharsView
    private lateinit var musicImg: ImageView
    private fun initView() {
        musicList = findViewById(R.id.music_list)
        musicPause = findViewById(R.id.music_pause)
        musicNext = findViewById(R.id.music_next)
        musicPrevious = findViewById(R.id.music_previous)
        musicLoopType = findViewById(R.id.music_loop_type)
        musicLocationIcon = findViewById(R.id.music_location_icon)
        songChars = findViewById(R.id.song_chars)
        musicImg = findViewById(R.id.music_img)
        musicProgress = findViewById(R.id.music_progress)
        manager = LinearLayoutManager(this)
        musicList.layoutManager = manager
        adapter = MusicsAdapter()

        adapter.onMusicItemClickListener = this
        musicList.adapter = adapter


        musicProgress.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                isSeekBarTouched = fromUser
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {}

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                if (isSeekBarTouched) {
                    val intent = Intent(this@SongActivity, PlayService::class.java)
                    intent.putExtra(
                        PlayService.SONG_ACTION_TYPE_KEY,
                        PlayService.SONG_ACTION_TYPE_SEEK_TO
                    )
                    intent.putExtra(PlayService.SONG_ACTION_TYPE_SEEK_KEY, seekBar?.progress)
//                    startService(intent)
                    startForegroundService(intent)
                    isSeekBarTouched = false
                }
            }
        })

        musicPause.setOnClickListener {
            if (SongHelper.getInstance().isPlaying) {
                SongHelper.getInstance().pauseOrPlay(PlayService.SONG_ACTION_TYPE_PAUSE)
                musicPause.setImageResource(R.mipmap.player_ic_play_blue)
            } else {
                if (SongHelper.getInstance().currentId == -1L) {//app重新打开
                    SongHelper.getInstance().playMusic(SongHelper.getInstance().currentId)
                } else {
                    SongHelper.getInstance().pauseOrPlay(PlayService.SONG_ACTION_TYPE_CONTINUE)
                }

                musicPause.setImageResource(R.mipmap.player_ic_pause_blue)
            }

            adapter.playStateChange()
        }

        musicNext.setOnClickListener {
//            SongHelper.getInstance().changeMusic(SongHelper.getInstance().getNext(SongHelper.getInstance().currentId)?.id!!)
            SongHelper.getInstance().playNext()
        }
        musicPrevious.setOnClickListener {
            SongHelper.getInstance().playPrevious()
        }

        musicLoopType.setImageResource(SongUtils.getLoopImg(PlayService.loopType))
        musicLoopType.setOnClickListener { setLoopType() }


        musicLocationIcon.setOnClickListener {
            scrollToCurrent(
                SongHelper.getInstance().getSongFromId(SongHelper.getInstance().currentId)!!
            )
        }

        songChars.onCharSelectListener = this
        songChars.setChars(SongHelper.getInstance().getChars())
        musicList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                when (newState) {
                    SCROLL_STATE_DRAGGING, SCROLL_STATE_IDLE -> {
                        songChars.setCurrentChar(
                            SongHelper.getInstance()
                                .getList()[manager.findFirstVisibleItemPosition()].sortString
                        )
                    }
                }
            }
        })

        SongHelper.getInstance().addTimeProgressListener(this)
    }

    override fun onTimeChange(currentTime: Int) {
        musicProgress.progress = currentTime
        musicTime.text =
            SongUtils.formatTime(currentTime) + "/" + SongUtils.formatTime(musicProgress.max)
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        PermissionUtils.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

    override fun onDestroy() {
        super.onDestroy()
        MyEventBus.getDefault().unregister(this, "onMusicPlayChange", SongStartEvent::class.java)
        MyEventBus.getDefault()
            .unregister(this, "onMusicPositionGetted", SongPositionEvent::class.java)
        MyEventBus.getDefault()
            .unregister(this, "onMusicStateChange", SongPlayStateEvent::class.java)
        MyEventBus.getDefault().unregister(this, "onLoopTyeChange", LoopEvent::class.java)
        MyEventBus.getDefault()
            .unregister(this, "onMusicListChanged", SongListChangeEvent::class.java)

        SongHelper.getInstance().removeTimeProgressListener(this)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMusicPlayChange(event: SongStartEvent) {
        adapter.setCurrent(event.songId)
        val song = SongHelper.getInstance().getSongFromId(event.songId)
        musicPause.setImageResource(R.mipmap.player_ic_pause_blue)
        SongHelper.getInstance().isPlaying = true
        updateSongInfo(song)
    }

    private fun updateSongInfo(song: Song?) {
        musicProgress.max = song?.duration!! / 1000
        musicProgress.progress = 0
        musicTime.text = "00:00/" + SongUtils.formatTime(musicProgress.max)

        musicName.text = song.name

        adapter.playStateChange()

        setSongImg(song)
    }

    private fun setSongImg(song: Song?) {
        val bitmap = SongHelper.getInstance().loadingCover(song?.path)

        if (bitmap != null) {
            musicImg.setImageBitmap(ImageUtils.toRoundCorner(bitmap, 200))
        } else {
            musicImg.setImageResource(R.mipmap.ic_logo)
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public fun onMusicPositionGetted(event: SongPositionEvent) {
        if (event.songId == -1L) {
            adapter.setCurrent(PreferenceUtils.getInstance().getLong("lastSongId", -1))
        } else {
            adapter.setCurrent(event.songId)
            musicProgress.max =
                SongHelper.getInstance().getSongFromId(event.songId)?.duration!! / 1000
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public fun onMusicStateChange(event: SongPlayStateEvent) {
        SongHelper.getInstance().isPlaying = event.isPlaying
        musicPause.setImageResource(if (event.isPlaying) R.mipmap.player_ic_pause_blue else R.mipmap.player_ic_play_blue)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public fun onLoopTyeChange(event: LoopEvent) {
        musicLoopType.setImageResource(SongUtils.getLoopImg(PlayService.loopType))
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public fun onMusicListChanged(event: SongListChangeEvent) {
        for (index in SongHelper.getInstance().getList().indices) {
            if (!TextUtils.isEmpty(newSongPath)) {
                adapter.position = index
                SongHelper.getInstance().playMusic(SongHelper.getInstance().getList()[index].id)
            } else if (SongHelper.getInstance()
                    .getList()[index].id == SongHelper.getInstance().currentId
            ) {
                adapter.position = index
            }
        }
        if (SongHelper.getInstance().currentId == -1L) {
            SongHelper.getInstance().currentId = SongHelper.getInstance().getList()[0].id
            adapter.setCurrent(0)
        }
        adapter.notifyDataSetChanged()

        updateSongInfo(SongHelper.getInstance().getSongFromId(SongHelper.getInstance().currentId))
    }

    override fun onMusicItemClick(position: Int, song: Song) {
        SongHelper.getInstance().playMusic(song.id)
        adapter.setCurrent(position)
    }

    private fun setLoopType() {
        val loopType = SongUtils.getNextLoopType(PlayService.loopType)
        val intent = Intent(this, PlayService::class.java)
        intent.putExtra(PlayService.SONG_ACTION_TYPE_KEY, loopType)
        startForegroundService(intent)
    }

    private fun scrollToCurrent(song: Song) {
        musicList.post {
            val position = SongHelper.getInstance().getList().indexOf(song)

            musicList.scrollBy(0, position * DpUtils.dp2Px(this, 62) - getScrollYDistance())
        }

        songChars.setCurrentChar(song.sortString)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        parseSongId(intent)
    }

    private var newSongPath = ""
    private fun parseSongId(intent: Intent?) {
        if (intent != null) {
            val id = intent.getLongExtra("songId", -1)
            if (id > 0) {
                SongHelper.getInstance().playMusic(id)
                scrollToCurrent(
                    SongHelper.getInstance().getList()[intent.getIntExtra(
                        "position",
                        0
                    )]
                )
            } else if (!TextUtils.isEmpty(intent.getStringExtra("path"))) {//新歌曲
                newSongPath = intent.getStringExtra("path") ?: ""
            }
        }
    }

    override fun onCharSelect(char: Char) {
        if (!ToastUtils.instance.isInited()) {
            ToastUtils.instance.init(applicationContext)
        }
        ToastUtils.instance.toast((char).toString())

        for ((index, item) in SongHelper.getInstance().getList().withIndex()) {
            if (item.sortChar == char) {
                musicList.scrollBy(0, index * DpUtils.dp2Px(this, 62) - getScrollYDistance())
                break
            }
        }
    }

    private fun getScrollYDistance(): Int {
        val layoutManager = musicList.layoutManager as LinearLayoutManager
        val position = layoutManager.findFirstVisibleItemPosition()
        val firstVisibleChildView: View? = layoutManager.findViewByPosition(position)
        val itemHeight: Int = firstVisibleChildView?.height ?: 0
        return position * itemHeight - (firstVisibleChildView?.top ?: 0)
    }


    override fun onPermissionDenied(permission: String) {
        super.onPermissionDenied(permission)
        Toast.makeText(MusicApplication.instance(), "请先打开读取存储权限", Toast.LENGTH_SHORT)
            .show()
    }

    override fun onPermissionGranted(permission: String) {
        super.onPermissionGranted(permission)
        SongHelper.getInstance().refreshList()
        adapter.notifyDataSetChanged()
    }
}